
package org.rishi.framework.db;

import java.io.File;
import java.io.FileOutputStream;
import java.sql.Connection;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;


/**
 * @author MHT E-mail:mht1984@126.com
 * @version 创建时间：2010-8-31 下午05:03:32
 *
 */
final class DBGenerator {

    // static Logger logger = LoggerFactory.getLogger(Generator.class);

    static int tableCount = 0;

    static int progress = 0;

    static StringBuffer e = new StringBuffer("");

    /**
     * 用于自动生成POJO和HTML
     * @param packageName	生成POJO报名
     * @param schema		生成POJO对应的库名
     * @param srcdir		指定输出路径（输出文件夹） 默认（当前用户目录/rishi-generated-code/）
     * @param superClass	集成自那个类
     * @param conn			数据库连接
     * @return
     * @throws Exception
     */
    public static String generateCode(String packageName, String schema,
                                      String srcdir, String superClass, Connection conn)
            throws Exception {

    	//如果没有指定pojo路径。默认
        if (srcdir == null)
            srcdir = System.getProperty("user.home") + File.separator  
                    + "rishi-generated-code";

        StringBuffer out = new StringBuffer();

        
        if ("".equals(schema))
            schema = null;

        e = new StringBuffer();

        if (superClass == null)
            superClass = "";
        else
            superClass = " extends " + superClass;

        String suffix = "Bean";

        StringTokenizer st = new StringTokenizer(packageName, ".");
        String path = "";
        //根据包名生成输出目录
        while (st.hasMoreTokens())
            path += File.separator + st.nextToken();

        path += File.separator;

        out.append("\n\nTimestamp: ").append(new Date());

        File srcDir = new File(srcdir + File.separator + "src" + File.separator
                + path);

        // File classes = new File(srcdir + File.separator + "classes");
        File jspDir = new File(srcdir + File.separator + "html");

        // create src or classes dirs
        // classes.mkdirs();
        srcDir.mkdirs();
        jspDir.mkdirs();

        out.append("\n\nHTML files will be generated in: ").append(jspDir.getCanonicalPath());
        out.append("\nPOJO source directory: ").append(srcDir.getCanonicalPath()).append("\n");
        out.append("\nJDBC Driver: ").append(conn.getMetaData().getDriverName());
        out.append("\nJDBC URL: ").append(conn.getMetaData().getURL());

        String javaCode;
        StringBuffer jspCode;

        String accessors;
        String flds;
        if (schema != null)
            out.append("\nFiltering on schema: ").append(schema);

        Set tables = SchemaUtil.getTables(conn, schema).keySet();
        // logger.warn("getTables");

        tableCount = tables.size();
        progress = 0;

        Iterator iter = tables.iterator();
        int count = 0;
        while (iter.hasNext()) {
            count++;
            progress++;
            String table = (String) iter.next();
            boolean create = true;
            Map fields = SchemaUtil.getColumns(table);
            String className = StringUtils.mixedCase(table);// + suffix;

            javaCode = "// Java code generated by Rishi on " + new Date()
                    + "\n";
            jspCode = new StringBuffer();

            String msg = "<p> ** HTML code generated by Rishi on " + new Date()
                    + " ** </p>\n\n";

            jspCode.append(msg).append("<fieldset>\n<legend>").append(table).append(" Form </legend>" + "\n<form action='#' method='post'>\n");

            if (packageName != null && !"".equals(packageName)) {
                javaCode += "package " + packageName + ";\n\n";
                jspCode.append("<p>\n\tPOJO = ").append(packageName).append(".").append(className).append("\n</p>\n");

            } else
                jspCode.append("<p>\n\tPOJO = ").append(className).append("\n</p>\n");

            jspCode
                    .append("<p>\n\t<input type='submit' value='Submit'/>\n</p>");

            e.append("  <entity class='").append(packageName).append(".").append(className).append("' name='").append(table.toLowerCase()).append("' />\n");

            StringBuffer j5 = new StringBuffer(javaCode);
            j5.append("//@Entity(name=\"").append(table).append("\")\n");
            j5.append("public class ").append(className).append(suffix).append(" implements java.io.Serializable {\n");
            javaCode += "public class " + className + superClass
                    + " implements java.io.Serializable {\n";

            accessors = "";
            flds = "";
            String flds2 = "";
            Map pk = SchemaUtil.getPrimaryKeys(table);

            if (pk.size() == 0) {

                String wrng = "Warning: Table <<"
                        + table
                        + ">> does not have a primary key defined! Rishi requires a primary key.";
                out.append(wrng);

            }

            Iterator iter2 = SchemaUtil.getColumns(table).keySet().iterator();
            // logger.warn("getColumns");
            String id = "";
            while (iter2.hasNext()) {
                String field = (String) iter2.next();
                Iterator pkIter = pk.keySet().iterator();
                while (pkIter.hasNext()) {
                    String pkValue = pkIter.next().toString();
                    if (pkValue.equalsIgnoreCase(field)) {
                        id = "\n\n    // @Id";
                        break;
                    } else
                        id = "";
                }
                accessors += StringUtils.createAccessor(field, (String) fields
                        .get(field));// name,type

                flds += "\n\n    private " + fields.get(field) + " " + field + ";";

                flds2 += id + "\n    private " + fields.get(field) + " " + field + ";";

                jspCode.append("\n<div style='margin: 10px'>\n\t<label for='").append(field).append("'>").append(field.toUpperCase()).append("</label><br>");

                jspCode.append("\n\t<input size='30' type='text' name='").append(field).append("' />\n</div>");

            }

            jspCode.append("\n</form>\n</fieldset>\n");

            javaCode += flds + accessors + "\n\n}";
            j5.append(flds2).append(accessors).append("\n\n}");

            String fileName = srcDir.getCanonicalPath() + File.separator + className + ".java";

            if (create) {

                File file;// = new File(fileName);
                if (true) {// (file.canRead() == false && file.createNewFile())
                    // {
                    FileOutputStream fout;
                    fileName = srcDir.getCanonicalPath() + File.separator
                            + className + suffix + ".java";
                    file = new File(fileName);
                    fout = new FileOutputStream(file);
                    fout.write(new String(j5).getBytes());
                    fout.flush();
                    fout.close();
                    out.append("\n\nCreating POJO... ").append(fileName);

                } else {
                    file = null;
                    out
                            .append("\nDid not create file... source file already exists");
                }

                // write a jsp file now
                // System.out.println(jspCode);
                File file2 = new File(jspDir.getCanonicalPath()
                        + File.separator + table.toLowerCase() + ".html");
                out.append("\nCreating HTML... ").append(file2.getCanonicalPath());
                FileOutputStream fout2 = new FileOutputStream(file2);
                fout2.write(new String(jspCode).getBytes());
                fout2.flush();
                fout2.close();

            }

        }

        conn.close();
        conn = null;
        return out.toString();

    }
}